package com.smh.demo1.a33;

import org.springframework.boot.DefaultBootstrapContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.support.SpringFactoriesLoader;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

/**
 * @author shiminghui
 * @date 2025/5/6 19:28
 * @description: TODO
 */

public class A33_2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

        SpringApplication.run(A33_2.class, args);
        SpringApplication springApplication = new SpringApplication(A33_2.class);

        springApplication.addListeners(event -> {
            System.out.println("\t事件为: " + event);
        });

        List<String> names = SpringFactoriesLoader.loadFactoryNames(SpringApplicationRunListener.class, A33_2.class.getClassLoader());
        for (String name : names) {
            // 根据类的名字创建对象
            System.out.println(name);
            Class<?> c = Class.forName(name);
            Constructor<?> constructor = c.getConstructor(SpringApplication.class, String[].class); // 获取构造器
            SpringApplicationRunListener publisher = (SpringApplicationRunListener) constructor.newInstance(springApplication, args); // 根据构造器创建对象

            DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
            publisher.starting(bootstrapContext); // spring boot 启动开始
            publisher.environmentPrepared(bootstrapContext, new StandardEnvironment()); // spring环境信息初始化完毕
            GenericApplicationContext context = new GenericApplicationContext();
            publisher.contextPrepared(context); // spring容器创建成功
            publisher.contextLoaded(context); // spring容器的Bean定义初始化完毕
            context.refresh();
            publisher.started(context); // spring容器初始化完毕
            publisher.running(context); // spring boot 启动成功
            publisher.failed(context, new Exception()); // 失败
        }

//        ConfigurableApplicationContext context = springApplication.run(args);
//
//        context.close();
        /*// 添加 app 监听器
        SpringApplication app = new SpringApplication();
        app.addListeners(e -> System.out.println(e.getClass()));

        // 获取事件发送器实现类名
        List<String> names = SpringFactoriesLoader.loadFactoryNames(SpringApplicationRunListener.class, A33_2.class.getClassLoader());
        for (String name : names) {
            System.out.println(name);
            Class<?> clazz = Class.forName(name);
            Constructor<?> constructor = clazz.getConstructor(SpringApplication.class, String[].class);
            SpringApplicationRunListener publisher = (SpringApplicationRunListener) constructor.newInstance(app, args);

            // 发布事件
            DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
            publisher.starting(bootstrapContext); // spring boot 开始启动
            publisher.environmentPrepared(bootstrapContext, new StandardEnvironment()); // 环境信息准备完毕
            GenericApplicationContext context = new GenericApplicationContext();
            publisher.contextPrepared(context); // 在 spring 容器创建，并调用初始化器之后，发送此事件
            publisher.contextLoaded(context); // 所有 bean definition 加载完毕
            context.refresh();
            publisher.started(context); // spring 容器初始化完成(refresh 方法调用完毕)
            publisher.running(context); // spring boot 启动完毕

            publisher.failed(context, new Exception("出错了")); // spring boot 启动出错
        }*/
    }
}
